home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dd / loadseg.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  24KB  |  990 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include    "defs.h"
  7. #include    "dbug_protos.h"
  8.  
  9.  
  10. // ************************************************************************
  11.  
  12. Prototype WORD        RefreshHunks(WORD maxLines, BOOL fullRefresh, LONG index);
  13. Prototype WORD        RefreshSymbols(WORD maxLines, BOOL fullRefresh, LONG index);
  14. Prototype LONG        SymbolIndexOfAddr(ULONG val);
  15. Prototype BOOL        DownHunks(void);
  16. Prototype BOOL        UpHunks(void);
  17. Prototype BOOL        DownSymbol(void);
  18. Prototype BOOL        PageDownSymbol(void);
  19. Prototype BOOL        UpSymbol(void);
  20. Prototype BOOL        PageUpSymbol(void);
  21.  
  22. Local BOOL        HunkError(ULONG hunkType);
  23. Prototype BOOL        DBugLoadSeg(char *filename);
  24. Prototype void        AllocateStack(void);
  25. Prototype void        ResetTarget(void);
  26. Prototype DEBUG     *FindDebug(ULONG address);
  27. Prototype DEBUG     *FindNearestDebug(ULONG address);
  28. Prototype SOURCE    *FindSource(DEBUG *debug, ULONG address);
  29. Prototype char        *FindSourceLine(DEBUG *debug, SOURCE *source);
  30. Prototype __stkargs char *LookupValue(ULONG value);
  31. Local       char        *LookupOffset(ULONG value,ULONG *symBuf);
  32. Prototype ULONG     *NearestSymbol(ULONG value);
  33. Prototype char        *NearestValue(ULONG value);
  34. Local BOOL        CompareLStrings(ULONG *s1, ULONG *s2);
  35. Prototype BOOL        LookupSymbol(char *symbol, ULONG *value);
  36. Prototype BOOL        LookupSymLen(char *symbol, UWORD len, ULONG *value);
  37. Prototype int        CountSymbols(void);
  38. Prototype void        CopySymbols(SYMLIST *symlist);
  39.  
  40. Prototype char        *addscore(char *string);
  41. Prototype char        *addat(char *string);
  42.  
  43. // ************************************************************************
  44.  
  45. UBYTE        *programStack = NULL;
  46. UBYTE        *programStackTop = NULL;
  47. ULONG        programStackSize = 32768;
  48.  
  49. // ************************************************************************
  50.  
  51. BOOL    DownHunks(void) {
  52.     CurDisplay->ds_LastRefreshTop = ++CurDisplay->ds_WindowTop;
  53.     ScrScrollup();
  54.     RefreshHunks(1, 0, CurDisplay->ds_WindowTop + ScrMainBodyRange(NULL,NULL) - 1);
  55.     return TRUE;
  56. }
  57.  
  58.  
  59. BOOL    UpHunks(void) {
  60.     if (CurDisplay->ds_WindowTop) {
  61.         CurDisplay->ds_LastRefreshTop = --CurDisplay->ds_WindowTop;
  62.         ScrScrolldown();
  63.         RefreshHunks(1, 0, CurDisplay->ds_WindowTop);
  64.     }
  65.     return TRUE;
  66. }
  67.  
  68.  
  69. WORD    RefreshHunks(WORD maxLines, BOOL fullRefresh, LONG index) {
  70.     WORD    count = 0;
  71.     HUNK    *thisHunk;
  72.     DEBUG    *debug;
  73.     ULONG    hunkNum;
  74.  
  75.     do_scroller();
  76.     if (fullRefresh) {
  77.         SetTitle(NULL,NULL);
  78.  
  79.         // add a separation line between hunks and register display
  80.         if(CurDisplay->ds_RegFlag) {
  81.             ++count;
  82.             Newline();
  83.             if (--maxLines == 0)return count;
  84.         }
  85.         ScrInverse();
  86.         ScrPuts("HUNK   TYPE     SIZE    ACTUAL   RELOCS   SYMBOL    LINE");
  87. //             xxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
  88.         count++;
  89.         Newline();
  90.         if (--maxLines == 0)return count;
  91.     }
  92.     ScrPlain();
  93.  
  94.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
  95.         if (index <= 0) {
  96.             ScrPrintf("%4d %08X %08X %08X %08X %08X %08X",
  97.                 hunkNum,
  98.                 thisHunk->type,
  99.                 thisHunk->size,
  100.                 thisHunk->actual,
  101.                 thisHunk->reloc32,
  102.                 thisHunk->symbols,
  103.                 thisHunk->debug
  104.             );
  105.             count++; ScrPutNewline(); maxLines--; if (!maxLines) return count;
  106.  
  107.         }
  108.         --index;
  109.         for (debug=thisHunk->debug; debug; debug = debug->link) {
  110.             if (index <= 0) {
  111.                 ScrPrintf("     %08X %s", debug->table[0].address, debug->sourceName);
  112. //                       xxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
  113.                 count++; 
  114.                 ScrPutNewline(); 
  115.                 maxLines--; 
  116.                 if (!maxLines) return count;
  117.             }
  118.             --index;
  119.         }
  120.     }
  121.     return count;
  122. }
  123.  
  124. BOOL    UpSymbol(void) {
  125.     if (CurDisplay->ds_WindowTop) {
  126.         CurDisplay->ds_LastRefreshTop = --CurDisplay->ds_WindowTop;
  127.         ScrScrolldown();
  128.         RefreshSymbols(1, 0, CurDisplay->ds_WindowTop);
  129.     }
  130.     return TRUE;
  131. }
  132.  
  133. BOOL    DownSymbol(void) {
  134.     CurDisplay->ds_LastRefreshTop = ++CurDisplay->ds_WindowTop;
  135.     ScrScrollup();
  136.     RefreshSymbols(1, 0, CurDisplay->ds_WindowTop + ScrMainBodyRange(NULL,NULL) - 1);
  137.     return TRUE;
  138. }
  139.  
  140. BOOL    PageDownSymbol(void) {
  141.     int lines = CalcDisplayLines();
  142.  
  143.     if(lines > 0) {
  144.     CurDisplay->ds_WindowTop += lines;
  145.     RefreshWindow(1);
  146.     }
  147.     return TRUE;
  148. }
  149.  
  150. BOOL    PageUpSymbol(void) {
  151.     int lines = CalcDisplayLines();
  152.  
  153.     if (CurDisplay->ds_WindowTop) {
  154.         if(lines > 0) {
  155.         CurDisplay->ds_WindowTop -= lines;
  156.         if((LONG)CurDisplay->ds_WindowTop < 0)CurDisplay->ds_WindowTop = 0;
  157.         RefreshWindow(1);
  158.     }
  159.     }
  160.     return TRUE;
  161. }
  162.  
  163. WORD    RefreshSymbols(WORD maxLines, BOOL fullRefresh, LONG index) {
  164.     ULONG    buf[32];
  165.     WORD    count = 0;
  166.     HUNK    *thisHunk;
  167.     ULONG    hunkNum, *symPtr;
  168.  
  169.     ScrPlain();
  170.     do_scroller();
  171.     if (fullRefresh && maxLines) { 
  172.         SetTitle(NULL,NULL);
  173.  
  174.  
  175.         // add a separation line between hunks and register display
  176.         if(CurDisplay->ds_RegFlag) {
  177.             ++count;
  178.             Newline();
  179.             if (--maxLines == 0)return count;
  180.         }
  181. #if 0
  182.         ScrInverse();
  183.         ScrPuts("ADDRESS  SYMBOL           VALUES");
  184. //             xxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
  185.         ScrPlain();
  186.         count++;
  187.         ScrPutNewline();
  188.         if (--maxLines == 0)return TRUE;
  189. #endif
  190.     }
  191.  
  192.  
  193.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
  194.         if (!(symPtr = thisHunk->symbols))continue;
  195.         while (*symPtr) {
  196.             if (index <= 0) {
  197.                 ULONG   *name = &symPtr[1];
  198.                 ULONG   i = symPtr[0] & 0x00FFFFFF;
  199.  
  200.                 for (i = 0; i < symPtr[0]; ++i)buf[i] = name[i];
  201.                 buf[i] = 0;
  202.                 if(IsBreakpoint(name[i]))ScrUnderline();
  203.                 else ScrPlain();
  204.                 ScrPrintf("%08X %-16.16s", name[i], buf);
  205.                 --maxLines;
  206.                 ++count;
  207.                 ScrPutNewline();
  208.                 if (maxLines == 0)return count;
  209.             }
  210.             --index;
  211.             symPtr = &symPtr[*symPtr + 2];
  212.         }
  213.     }
  214.     return count;
  215. }
  216.  
  217. /*
  218.  *
  219.  *
  220.  */
  221.  
  222. LONG    SymbolIndexOfAddr(ULONG val) {
  223.     HUNK    *thisHunk;
  224.     LONG    index = 0;
  225.     ULONG    hunkNum;
  226.     ULONG    *sym;
  227.  
  228.     if ((sym = NearestSymbol(val)) == NULL)
  229.         return 0;
  230.  
  231.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
  232.         ULONG    *symPtr;
  233.  
  234.         if ((symPtr = thisHunk->symbols) == NULL)
  235.             continue;
  236.  
  237.         //  Scan symbols
  238.         //  [namelen][name][value]
  239.  
  240.         while (*symPtr) {
  241.             if (symPtr == sym)
  242.                 return(index);
  243.             symPtr = symPtr + (*symPtr + 2);
  244.             ++index;
  245.         }
  246.     }
  247.     return 0;
  248. }
  249.  
  250. // ************************************************************************
  251.  
  252. #define DPRINTF     FALSE
  253.  
  254. #if DPRINTF
  255. #define dprintf kprintf
  256. #else
  257. #define dprintf //
  258. #endif
  259.  
  260.  
  261. ULONG    *exeFile;
  262. ULONG    exeSize = 0;
  263. ULONG    numHunks, firstHunk, lastHunk;
  264. HUNK    *hunkArray;
  265.  
  266. Local BOOL    HunkError(ULONG hunkType) {
  267.     printf("*** Hunk Error: $%08X\n", hunkType);
  268.     return FALSE;
  269. }
  270.  
  271. BOOL    DBugLoadSeg(char *filename) {
  272.     int    fd;
  273.     ULONG    i, hunkType, *nextHunk;
  274.     HUNK    *thisHunk = NULL;
  275.     ULONG    *exePtr;
  276.     ULONG   *lasthunk = NULL;
  277.  
  278.     fd = open(filename, O_READ);
  279.     if (fd == -1) return FALSE;
  280.     exeSize = lseek(fd, 0, 2); lseek(fd, 0, 0);
  281.     exeSize += 3; exeSize >>= 2;
  282.     exeFile = (ULONG *)MallocPublic(exeSize*4+4);
  283.     if (!exeFile) { close(fd); return FALSE; }
  284.     read(fd, exeFile, exeSize*4);
  285.     close(fd);
  286.     exeFile[exeSize] = 0;
  287.  
  288.     exePtr = exeFile;
  289.     if (*exePtr != HUNK_HEADER) { Free(exeFile); exeFile = 0; return FALSE; }
  290.     while (1) {
  291.         hunkType = *exePtr++;
  292. dprintf("HUNK TYPE is %lx == ",hunkType);
  293.         switch ( hunkType & 0x3fffffff ) {
  294.             case NULL:            // 0
  295. dprintf("NULL\n");
  296.                 return TRUE;
  297.             case HUNK_UNIT:         // 999
  298. dprintf("HUNK_UNIT\n");
  299.                 return HunkError(hunkType);
  300.             case HUNK_NAME:         // 1000
  301. dprintf("HUNK_NAME\n");
  302.                 return HunkError(hunkType);
  303.             case HUNK_CODE:         // 1001
  304. #if    DPRINTF
  305. dprintf("HUNK_CODE\n");
  306. goto qwe;
  307. #endif
  308.             case HUNK_DATA:         // 1002
  309. #if    DPRINTF
  310. dprintf("HUNK_DATA\n");
  311. goto qwe;
  312. #endif
  313.             case HUNK_BSS:            // 1003
  314. #if    DPRINTF
  315. dprintf("HUNK_BSS\n");
  316. qwe:
  317. #endif
  318.                 if (!thisHunk) return FALSE;
  319.                 thisHunk->type = hunkType;
  320.                 thisHunk->reloc32 = NULL;
  321.                 thisHunk->debug = NULL;
  322.                 thisHunk->symbols = NULL;
  323.                 thisHunk->hSize = *exePtr++;
  324.                 thisHunk->hunk = exePtr;
  325.                 if ((thisHunk->type & 0x3fffffff) != HUNK_BSS) {
  326.                 // skip over code/data section
  327.                 exePtr = &exePtr[thisHunk->hSize];
  328.                 }
  329.                 i = (thisHunk->size << 2) + 4 ; // size of hunk in bytes
  330.                               // (inc. next hunk link)
  331.  
  332.                 // special new memory allocation defined in 2.04 AmigaDOS
  333.                 if (((thisHunk->type & ((1<<31)|(1<<30))) == ((1<<31)|(1<<30)))) { // any
  334.                 ULONG memtype = (*exePtr++) & 0x00FFFFFF;
  335.                 thisHunk->memptr = (ULONG *)MallocAny(i,memtype);
  336.                 }
  337.                 else if (thisHunk->type & (1<<31)) {     // fast
  338.                 thisHunk->memptr = (ULONG *)MallocFast(i);
  339.                 }
  340.                 else if (thisHunk->type & (1<<30)) {    // chip
  341.                 thisHunk->memptr = (ULONG *)MallocChip(i);
  342.                 }
  343.                 else {                    // public
  344.                 thisHunk->memptr = (ULONG *)MallocPublic(i);
  345.                 }
  346.                 if (!thisHunk->memptr) {
  347.                 printf("*** Can't allocate memory for hunk\n");
  348.                 return FALSE;
  349.                 }
  350.  
  351.                 // skip past the link to next hunk
  352.                 thisHunk->actual = thisHunk->memptr + 1;
  353.                 dprintf("Allocation at %lx\n",thisHunk->actual);
  354.                 // check Scroller Range Settings
  355.                 if((thisHunk->type & 0x3fffffff) == HUNK_CODE) {
  356.                     if((ULONG)thisHunk->actual < ScrollStart)
  357.                       ScrollStart = (unsigned long)thisHunk->actual;
  358.                 if((ULONG)(thisHunk->actual + i/4) > ScrollEnd)
  359.                     ScrollEnd = (unsigned long)thisHunk->actual + i/4;
  360.                 }
  361.  
  362.                 // store the link to this hunk in the previous hunk
  363.                 if(lasthunk) {
  364.                 *lasthunk = MKBADDR((ULONG *)thisHunk->memptr);
  365.                 }
  366.                 lasthunk = thisHunk->memptr;
  367.  
  368.  
  369.                 break;
  370.             case HUNK_RELOC32:        // 1004
  371. dprintf("HUNK_RELOC32\n");
  372.                 if (!thisHunk) return FALSE;
  373.                 thisHunk->reloc32 = exePtr;
  374.                 while (i = *exePtr++) exePtr = &exePtr[i+1];
  375.                 break;
  376.             case HUNK_RELOC16:        // 1005
  377. dprintf("HUNK_RELOC16\n");
  378.                 return HunkError(hunkType);
  379.             case HUNK_RELOC8:        // 1006
  380. dprintf("HUNK_RELOC8\n");
  381.                 return HunkError(hunkType);
  382.             case HUNK_EXT:            // 1007
  383. dprintf("HUNK_EXT\n");
  384.                 return HunkError(hunkType);
  385.             case HUNK_SYMBOL:        // 1008
  386. dprintf("HUNK_SYMBOL\n");
  387.                 if (!thisHunk) return FALSE;
  388.                 thisHunk->symbols = exePtr;
  389.                 while (i = *exePtr++) {
  390.                     exePtr = &exePtr[i];
  391.                     *exePtr += (ULONG)thisHunk->actual;
  392.                     exePtr++;
  393.                 }
  394.                 break;
  395.             case HUNK_DEBUG:        // 1009
  396. dprintf("HUNK_DEBUG\n");
  397.                 if (!thisHunk) return FALSE;
  398.                 i = *exePtr++;
  399.                 nextHunk = &exePtr[i];
  400.                 i = (ULONG)thisHunk->actual;
  401.                 i += *exePtr++;     // address that offsets in table are from
  402.                 if (*exePtr++ == 'LINE') {
  403.                     DEBUG    *dbg = (DEBUG *)MallocPublic(sizeof(DEBUG));
  404.                     ULONG    base = i, *pl;
  405.  
  406.                     if (!dbg) {
  407.                         printf("Can't allocate DEBUG structure\n");
  408.                         exit(20);
  409.                     }
  410.                     dbg->link = thisHunk->debug;
  411.                     thisHunk->debug = dbg;
  412.                     for (i=0; i<128; i++) dbg->sourceName[i] = '\0';
  413.                     i = *exePtr++;    // length of filename in longs
  414.                     pl = (ULONG *)&dbg->sourceName[0];
  415.                     while (i > 0) { *pl++ = *exePtr++; --i; }
  416.                     dbg->table = (SOURCE *)exePtr;
  417.                     dbg->tableEnd = (SOURCE *)nextHunk;
  418.                     // read in the source file
  419.                     dbg->source = NULL;
  420.                     {
  421.                         int fd = open(dbg->sourceName, O_READ);
  422.                         if (fd != -1) {
  423.                             i = lseek(fd, 0, 2); lseek(fd, 0, 0);
  424.                             dbg->source = (char *)MallocPublic(i+1);
  425.                             if (dbg->source) {
  426.                                 read(fd, dbg->source, i);
  427.                                 dbg->source[i] = '\0';
  428.                             }
  429.                             close(fd);
  430.                         }
  431.                     }
  432.  
  433.                     // relocate line#/offset pair table
  434.                     // determine bounds of debugger hunk
  435.                     //   XXX can miss code inbetween linked
  436.                     //     object modules, addresses are
  437.                     //     not right up against each other
  438.  
  439.                     {
  440.                         SOURCE    *ps;
  441.                         for (ps = dbg->table; ps != dbg->tableEnd; ps++)
  442.                             ps->address += base;
  443.  
  444.                         if (ps != dbg->table) {
  445.                             dbg->addrBegin = dbg->table->address;
  446.                             dbg->addrEnd   = (ps-1)->address;
  447.                         }
  448.                     }
  449.                 }
  450.                 exePtr = nextHunk;
  451.                 break;
  452.             case HUNK_END:            // 1010
  453. dprintf("HUNK_END\n");
  454.                 thisHunk++;
  455.                 break;
  456.             case HUNK_HEADER:        // 1011
  457. dprintf("HUNK_HEADER\n");
  458.                 while (i = *exePtr++) exePtr = &exePtr[i];    // skip libs
  459.                 numHunks = *exePtr++;
  460.                 firstHunk = *exePtr++;
  461.                 lastHunk = *exePtr++;
  462.                 hunkArray = (HUNK *)MallocPublic(sizeof(HUNK) * numHunks);
  463.                 if (!hunkArray) {
  464.                     printf("*** Insufficient memory for HunkHeader table\n");
  465.                     exit(20);
  466.                 }
  467.                 // fetch hunk sizes from the header and store in hunkArray
  468.                 for (i=0; i<numHunks; i++) hunkArray[i].size = *exePtr++;
  469.                 thisHunk = hunkArray;
  470.                 break;
  471. //            case HUNK_INVALID:        // 1012
  472. //dprintf("case HUNK_INVALID\n");
  473. //                return HunkError(hunkType);
  474.             case HUNK_OVERLAY:        // 1013
  475. dprintf("HUNK_OVERLAY\n");
  476.                 return HunkError(hunkType);
  477.             case HUNK_BREAK:        // 1014
  478. dprintf("HUNK_BREAK\n");
  479.                 return HunkError(hunkType);
  480.             case HUNK_DREL32:        // 1015
  481. dprintf("HUNK_DREL32\n");
  482.                 return HunkError(hunkType);
  483.             case HUNK_DREL16:        // 1016
  484. dprintf("HUNK_DREL16\n");
  485.                 return HunkError(hunkType);
  486.             case HUNK_DREL8:        // 1017
  487. dprintf("HUNK_DREL8\n");
  488.                 return HunkError(hunkType);
  489.             case HUNK_LIB:            // 1018
  490. dprintf("HUNK_LIB\n");
  491.                 return HunkError(hunkType);
  492.             case HUNK_INDEX:        // 1019
  493. dprintf("HUNK_INDEX\n");
  494.                 return HunkError(hunkType);
  495.         default:;
  496. dprintf("Unknown hunk type %lx\n",hunkType);
  497.             break;
  498.         }
  499.     }
  500. }
  501.  
  502. void    AllocateStack(void) {
  503.     if (!programStack) {
  504.         // reset stack size to CLI stack size if CLU default
  505.         // stack is larger than 32K
  506.         programStackSize = MAX(thisCli->cli_DefaultStack * 4, programStackSize);
  507.         programStack = (UBYTE *)MallocPublic(programStackSize);
  508.         if(!programStack) {
  509.             printf("Can't Allocate Program Stack!\n");
  510.             exit(20);
  511.         }
  512.         programStackTop = &programStack[programStackSize];
  513.     }
  514. }
  515.  
  516. void    ResetTarget(void) {
  517.     HUNK        *thisHunk = &hunkArray[0];
  518.     ULONG        i;
  519.     struct FileHandle *fh;
  520.     char    *pd;
  521.  
  522.     AllocateStack();
  523.     for (i=0; i<numHunks; i++, thisHunk++) {
  524.         switch (thisHunk->type & 0x3fffffff) {
  525.         // code and data hunks are copied from the file into allocated memory.
  526.         // then the reloc32 hunk is applied to relocate the copied hunk.
  527.         case HUNK_CODE:
  528.         case HUNK_DATA: { // copy the hunk
  529.             ULONG    *ps = thisHunk->hunk, *pd = thisHunk->actual;
  530.             ULONG    i = thisHunk->hSize;
  531.             while (i > 0) { 
  532.             *pd++ = *ps++; 
  533.             --i;
  534.             }
  535.         }
  536.         { // relocations
  537.             UBYTE    *base = (UBYTE *)thisHunk->actual;
  538.             ULONG    offset, *src = thisHunk->reloc32;
  539.             ULONG    hunkNumber, numRelocs;
  540.  
  541.             if (!src) break;    // no reloc32 hunk
  542.             numRelocs = *src++;
  543.             while (numRelocs) {
  544.             hunkNumber = *src++;
  545.             offset = (ULONG)hunkArray[hunkNumber].actual;
  546.             while (numRelocs) {
  547.                 *(ULONG *)&base[*src++] += offset;
  548.                 numRelocs--;
  549.             }
  550.             numRelocs = *src++;
  551.             }
  552.         }
  553.         break;
  554.         case HUNK_BSS:
  555.             break;
  556.         default:;
  557. dprintf("UNKNOWN HUNK in RESET\n");
  558.         break;
  559.         }
  560.     }
  561.     // Load Input() with command line, if any
  562.     // (A debugger has to do shell like things, occasionally
  563.     if((fh = (struct FileHandle *)BADDR(Input()))) {
  564.         Flush(Input());
  565.         pd = (char *)BADDR(fh->fh_Buf);
  566.         strcpy(pd,"");
  567.         strncat(pd,args,argSize-1);
  568.         strcat(pd,"\n");
  569.         fh->fh_Pos = 0;
  570.         fh->fh_End = strlen(pd);
  571.     }
  572.  
  573.     // initialize registers
  574.     lastState = programState = STATE_RESET;
  575.     lastPC = programPC = (ULONG)hunkArray[0].actual;
  576.     lastSR = programSR = 0;
  577.  
  578.     lastA0 = programA0 = (ULONG)args;
  579.     lastD0 = programD0 = argSize;
  580.  
  581.     lastD1 = lastD2 = lastD3 = lastD4 = lastD5 = lastD6 = lastD7 =
  582.         programD1 = programD2 = programD3 = programD4 = programD5 = programD6 = programD7 = 0;
  583.     lastA1 = lastA2 = lastA3 = lastA4 = lastA5 = lastA6 =
  584.         programA1 = programA2 = programA3 = programA4 = programA5 = programA6 = 0;
  585.     programA7 = (ULONG)&programStack[programStackSize];
  586.  
  587.     // BCPL programs are going to want A1, A2, A5, and A6 to be
  588.     // set up properly.  The easiest place to get this is from
  589.     // our own stack
  590.     {
  591.            long *stacktop;
  592.         long *clistack;
  593.  
  594.  
  595.         // get pointer to top of our stack
  596.            stacktop = ((struct Process *)(SysBase->ThisTask))->pr_ReturnAddr;  
  597.  
  598.         // get last value of CLI stack
  599.            clistack   = (long *) *(++stacktop);
  600.  
  601.         lastA1 = programA1 =(ULONG)(*(++clistack));
  602.         lastA2 = programA2 =(ULONG)(*(++clistack));
  603.         lastA5 = programA5 =(ULONG)(*(++clistack));
  604.         lastA6 = programA6 =(ULONG)(*(++clistack));
  605.  
  606.  
  607.     { // push "catcher" address on program stack
  608.         ULONG    *a7 = (ULONG *)programA7;
  609.         --a7;    // put half the stack size (in longs) on stack
  610.         *a7 = programStackSize/4;
  611.         --a7;
  612.         *a7 = (ULONG)TargetExit;
  613.         lastA7 = programA7 = (ULONG)a7;
  614.     }
  615.  
  616.     }
  617.  
  618.     if (LookupSymbol("@main", &i) || LookupSymbol("_main", &i)) {
  619.         SetTempBreakpoint(i);
  620.         GoTarget();
  621.     }
  622.  
  623.     CurDisplay->ds_WindowTop = programPC;
  624.     CurDisplay->ds_WindowTopLine = 0;
  625.  
  626.     // set the default save address tables
  627.     SetModeSave(DISPLAY_BYTES);
  628.     SetModeSave(DISPLAY_SOURCE);
  629. }
  630.  
  631. DEBUG    *FindDebug(ULONG address) {
  632.     DEBUG        *debug;
  633.     SOURCE        *source;
  634.  
  635.     if (debug = FindNearestDebug(address)) {
  636.         for (source = debug->table; source != debug->tableEnd; ++source) {
  637.             if (source->address == address)break;
  638.         }
  639.         debug = NULL;
  640.     }
  641.     return(debug);
  642. }
  643.  
  644. #ifdef NOTDEF    // REMOVED
  645.  
  646. DEBUG    *FindDebug(ULONG address) {
  647.     HUNK        *thisHunk;
  648.     ULONG        hunkNum, hunkStart, hunkEnd;
  649.     DEBUG        *debug;
  650.     SOURCE        *source;
  651.  
  652.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
  653.         hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
  654.         if (address < hunkStart || address > hunkEnd) continue;
  655.         debug = thisHunk->debug;
  656.         while (debug) {
  657.             source = debug->table;
  658.             while (source != debug->tableEnd) {
  659.                 if (source->address == address) return debug;
  660.                 source++;
  661.             }
  662.             debug = debug->link;
  663.         }
  664.     }
  665.     return NULL;
  666. }
  667.  
  668. #endif
  669.  
  670. DEBUG    *FindNearestDebug(ULONG address) {
  671.     HUNK        *thisHunk;
  672.     ULONG        hunkNum, hunkStart, hunkEnd;
  673.     DEBUG        *debug;
  674.  
  675.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
  676.         hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
  677.         if (address < hunkStart || address > hunkEnd) continue;
  678.  
  679.         for (debug = thisHunk->debug; debug; debug = debug->link) {
  680.             if (address >= debug->addrBegin && address <= debug->addrEnd)
  681.                 return(debug);
  682.         }
  683.     }
  684.     return NULL;
  685. }
  686.  
  687.  
  688. SOURCE    *FindSource(DEBUG *debug, ULONG address) {
  689.     SOURCE    *source;
  690.  
  691.     source = debug->table;
  692.     if (source) {
  693.         while (source != debug->tableEnd) {
  694.             if (source->address == address) return source;
  695.             source++;
  696.             if (source != debug->tableEnd && source->address > address) {
  697.                 --source;
  698.                 return source;
  699.             }
  700.         }
  701.     }
  702.     return NULL;
  703. }
  704.  
  705. char    *FindSourceLine(DEBUG *debug, SOURCE *source) {
  706.     char    *line = debug->source;
  707.     ULONG    currentLine = 1;
  708.  
  709.     if(line) {
  710.     while (currentLine < source->lineNumber) {
  711.         while (*line && (*line != '\n')) {
  712.             *line++;
  713.         }
  714.         if (*line) line++;
  715.         currentLine++;
  716.     }
  717.     if (*line) return line;
  718.     }
  719.     return NULL;
  720. }
  721.  
  722. __stkargs char    *LookupValue(ULONG value) {
  723.     HUNK        *thisHunk;
  724.     ULONG        i, hunkNum, *symPtr, *name;
  725.     ULONG        hunkStart, hunkEnd;
  726.     ULONG        *ps, *pd;
  727.     static ULONG    symBuf[64];
  728.  
  729.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; 
  730.         thisHunk++, hunkNum++) {
  731.         hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
  732.         if (value < hunkStart || value > hunkEnd) continue;
  733.         symPtr = thisHunk->symbols;
  734.         if (!symPtr) return NULL;
  735.         while (*symPtr) {
  736.             name = symPtr;
  737.             i = *symPtr++;
  738.             symPtr = &symPtr[i];
  739.             if (*symPtr++ == value) {
  740.                 for (i=0; i<64; i++) symBuf[i] = 0;
  741.                 pd = &symBuf[0];
  742.                 i = *name++;
  743.                 ps = name;
  744.                 while (i > 0) { *pd++ = *ps++; --i; }
  745.                 return (char *)&symBuf[0];
  746.             }
  747.         }
  748.         return LookupOffset(value,symBuf); // return NULL;
  749.     }
  750.     return LookupOffset(value,symBuf); // return NULL;
  751. }
  752.  
  753. char    *LookupOffset(ULONG value,ULONG *symBuf) {
  754.     char *s;
  755.     ULONG val;
  756.  
  757.     if(CurDisplay->ds_DisplayOffsets) {
  758.     if(s = NearestValue(value)) {
  759.         LookupSymbol(s,&val);
  760.         sprintf((char *)&symBuf[0],"%s + $%04X",s,value-val);
  761.         return (char *)&symBuf[0];
  762.     }
  763.     }
  764.     return NULL;
  765. }
  766.  
  767. ULONG    *NearestSymbol(ULONG value) {
  768.     HUNK        *thisHunk;
  769.     ULONG        i, hunkNum, *symPtr, *name, diff = 0x7fffffff, *found;
  770.     ULONG        hunkStart, hunkEnd;
  771.  
  772.     found = NULL;
  773.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
  774.         hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
  775.         if (value < hunkStart || value > hunkEnd) continue;
  776.         symPtr = thisHunk->symbols;
  777.         if (!symPtr) return NULL;
  778.         while (*symPtr) {
  779.             name = symPtr;
  780.             i = *symPtr++;
  781.             symPtr = &symPtr[i];
  782.             if (*symPtr == value) { found = name; break; }
  783.             if (*symPtr < value && value - *symPtr < diff) { found = name; diff = value - *symPtr; }
  784.             symPtr++;
  785.         }
  786.         return found;
  787.     }
  788.     return NULL;
  789. }
  790.  
  791. char    *NearestValue(ULONG value) {
  792.     ULONG    *found;
  793.     ULONG    *ps, *pd;
  794.     LONG    i;
  795.     static ULONG    symBuf[64];
  796.  
  797.     if (found = NearestSymbol(value)) {
  798.         for (i=0; i<64; i++) symBuf[i] = 0;
  799.         pd = &symBuf[0];
  800.         i = *found++;
  801.         ps = found;
  802.         while (i > 0) { *pd++ = *ps++; --i; }
  803.         return (char *)&symBuf[0];
  804.     }
  805.     return(NULL);
  806. }
  807.  
  808.  
  809. #ifdef NOTDEF
  810.  
  811. //
  812. //        REMOVED
  813. //
  814.  
  815. char    *NearestValue(ULONG value) {
  816.     HUNK        *thisHunk;
  817.     ULONG        i, hunkNum, *symPtr, *name, diff = 0x7fffffff, *found;
  818.     ULONG        hunkStart, hunkEnd;
  819.     ULONG        *ps, *pd;
  820.     static ULONG    symBuf[64];
  821.  
  822.     found = NULL;
  823.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
  824.         hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
  825.         if (value < hunkStart || value > hunkEnd) continue;
  826.         symPtr = thisHunk->symbols;
  827.         if (!symPtr) return NULL;
  828.         while (*symPtr) {
  829.             name = symPtr;
  830.             i = *symPtr++;
  831.             symPtr = &symPtr[i];
  832.             if (*symPtr == value) { found = name; break; }
  833.             if (*symPtr < value && value - *symPtr < diff) { found = name; diff = value - *symPtr; }
  834.             symPtr++;
  835.         }
  836.         if (found) {
  837.             for (i=0; i<64; i++) symBuf[i] = 0;
  838.             pd = &symBuf[0];
  839.             i = *found++;
  840.             ps = found;
  841.             while (i > 0) { *pd++ = *ps++; --i; }
  842.             return (char *)&symBuf[0];
  843.         }
  844.         return NULL;
  845.     }
  846.     return NULL;
  847. }
  848.  
  849. #endif
  850.  
  851. Local BOOL    CompareLStrings(ULONG *s1, ULONG *s2) {
  852.     ULONG len = *s1++;
  853.     if (len != *s2++) return FALSE;
  854.     while (len > 0) {
  855.         if (*s1++ != *s2++) return FALSE;
  856.         len--;
  857.     }
  858.     return TRUE;
  859. }
  860.  
  861. int    CountSymbols(void) {
  862.     HUNK        *thisHunk;
  863.     ULONG        i, hunkNum, *symPtr;
  864.     int symcount = 0;
  865.  
  866.     for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks;
  867.                             thisHunk++,hunkNum++){
  868.         symPtr = thisHunk->symbols;
  869.         if (!symPtr) continue;
  870.         while (*symPtr) {
  871.             i = *symPtr++;
  872.             symPtr = &symPtr[i];
  873.             symPtr++;
  874.             symcount++;
  875.         }
  876.     }
  877.     return symcount;
  878. }
  879.  
  880. BOOL    LookupSymbol(char *symbol, ULONG *value) {
  881.     HUNK        *thisHunk;
  882.     ULONG        i, hunkNum, *symPtr, *name;
  883.     UBYTE        *ps, *pd;
  884.     ULONG        symBuf[64];
  885.  
  886.     for (i=0; i<64; i++) {
  887.         symBuf[i] = 0;
  888.     }
  889.  
  890.     ps = (UBYTE *)symbol; 
  891.     pd = (UBYTE *)&symBuf[1];
  892.  
  893.     i = 0;
  894.     while (*pd++ = *ps++) i++;
  895.     i += 3;
  896.     i /= 4;
  897.     symBuf[0] = i;
  898.  
  899.  
  900.     for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks;
  901.                             thisHunk++,hunkNum++){
  902.         symPtr = thisHunk->symbols;
  903.         if (!symPtr) continue;
  904.         while (*symPtr) {
  905.             name = symPtr;
  906.             i = *symPtr++;
  907.             symPtr = &symPtr[i];
  908.             if (CompareLStrings(symBuf, name)) {
  909.                 *value = *symPtr;
  910.                 return TRUE;
  911.             }
  912.             symPtr++;
  913.         }
  914.     }
  915.     return FALSE;
  916. }
  917.  
  918.  
  919. void    CopySymbols(SYMLIST *symlist) {
  920.     HUNK        *thisHunk;
  921.     ULONG        i, hunkNum, *symPtr, *name;
  922.     int         j = 0;
  923.  
  924.     for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks; thisHunk++,hunkNum++){
  925.         symPtr = thisHunk->symbols;
  926.         if (!symPtr) continue;
  927.         while (*symPtr) {
  928.             name = symPtr;
  929.             i = *symPtr++;
  930.             symPtr = &symPtr[i];
  931.             symlist[j].symbolname = name;
  932.             symlist[j].address = *symPtr;
  933.             j++;
  934.             symPtr++;
  935.         }
  936.     }
  937. }
  938.  
  939. BOOL    LookupSymLen(char *symbol, UWORD len, ULONG *value) {
  940.     HUNK        *thisHunk;
  941.     ULONG        i, hunkNum, *symPtr, *name;
  942.     UBYTE        *ps, *pd;
  943.     ULONG        symBuf[64];
  944.  
  945.     ps = (UBYTE *)symbol; pd = (UBYTE *)&symBuf[1];
  946.     for (i=0; i<64; i++) symBuf[i] = 0;
  947.     for (i = 0; i<len; i++) *pd++ = *ps++;
  948.     *pd = '\0';
  949.     i += 3;
  950.     i /= 4;
  951.     symBuf[0] = i;
  952.  
  953.     for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
  954.         symPtr = thisHunk->symbols;
  955.         if (!symPtr) continue;
  956.         while (*symPtr) {
  957.             name = symPtr;
  958.             i = *symPtr++;
  959.             symPtr = &symPtr[i];
  960.             if (CompareLStrings(symBuf, name)) {
  961.                 *value = *symPtr;
  962.                 return TRUE;
  963.             }
  964.  
  965.             symPtr++;
  966.         }
  967.     }
  968.     return FALSE;
  969. }
  970.  
  971. char *addscore(char *string)
  972. {
  973. static char buffer[256];
  974.  
  975. strcpy(&buffer[1],string);
  976. buffer[0]='_';
  977.  
  978. return buffer;
  979. }
  980.  
  981.  
  982. char *addat(char *string)
  983. {
  984. static char buffer[256];
  985.  
  986. strcpy(&buffer[1],string);
  987. buffer[0]='@';
  988.  
  989. return buffer;
  990. }